<template>
    <a-dropdown
        :popPlacement="popPlacement"
        :useTargetWidth="false"
        class="a-input-date"
        v-model:popShown="popShown"
        :trigger="'none'"
    >
        <a-control-group class="a-input-date">
            <a-input-string
                class="c-w-100"
                :color="myColor"
                :size="mySize"
                :sharp="mySharp"
                :disabled="myDisabled"
                :value="displayText"
                :placeholder="placeholder"
                :readonly="true"
                :clearable="clearable"
                :isInner="true"
                @click="popShown = !popShown"
                @clear="input(null)"
            ></a-input-string>
            <a-button
                v-if="attachButtonShown"
                class="c-f-shrink-0"
                :color="myColor"
                :size="mySize"
                :sharp="mySharp"
                :disabled="myDisabled"
                :square="true"
                ref="btn"
                @click="popShown = !popShown"
                ><span class="fa fa-fw fa-calendar"></span></a-button
        ></a-control-group>

        <template v-slot:pop>
            <div
                class="pop"
                :class="[
                    !sharp ? `c-round-${mySize}` : '',
                    `c-p-${mySize}`,
                    `c-shadow-${mySize}`,
                ]"
                :style="{ width: popWidth + 'px' }"
            >
                <div v-if="isShowYear" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <div
                            class="c-f-h c-f-s-center"
                            :class="[
                                `c-height-${mySize}`,
                                `c-font-size-${mySize}`,
                                `c-p-h-${mySize}`,
                                `c-front-color-${myColor}-reverse`,
                            ]"
                        >
                            <span
                                >{{ currentYearTimespan.min }} -
                                {{ currentYearTimespan.max }}</span
                            >
                        </div>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastPeriod')"
                                :halfHeight="true"
                                @click="
                                    currentYearTimespan.min -= 20;
                                    currentYearTimespan.max -= 20;
                                "
                            >
                                <span class="fa fa-fw fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :disabled="myDisabled"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextPeriod')"
                                :halfHeight="true"
                                @click="
                                    currentYearTimespan.min += 20;
                                    currentYearTimespan.max += 20;
                                "
                            >
                                <span class="fa fa-fw fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <a-button
                            v-for="a in getArrayFromNumberSpan(
                                currentYearTimespan.min,
                                currentYearTimespan.max
                            )"
                            :key="a"
                            style="width: 20%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="yearClick(a)"
                        >
                            {{ a }}
                        </a-button>
                    </div>
                </div>
                <div v-else-if="isShowMonth" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            :title="$t('AInputDate.SelectYear')"
                            @click="
                                isShowYear = true;
                                isShowMonth = false;
                            "
                        >
                            <span>{{ tempResultInDayjs.format("YYYY") }}</span>
                            <span
                                >-<span class="animate-flash">__</span
                                >-__&#160;&#160;__:__:__</span
                            >
                        </a-button>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastYear')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(-1, 'year')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-fw fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextYear')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(1, 'year')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-fw fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <a-button
                            v-for="a in 12"
                            :key="a"
                            style="width: 25%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="monthClick(a)"
                        >
                            {{ a }}
                        </a-button>
                    </div>
                </div>
                <div v-else-if="isShowDate" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            :title="$t('AInputDate.SelectMonth')"
                            @click="
                                isShowMonth = true;
                                isShowDate = false;
                            "
                        >
                            <span>{{
                                tempResultInDayjs.format("YYYY-MM")
                            }}</span>
                            <span
                                >-<span class="animate-flash">__</span
                                >&#160;&#160;__:__:__</span
                            >
                        </a-button>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastMonth')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(-1, 'month')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-fw fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextMonth')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(1, 'month')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-fw fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h">
                        <div
                            v-for="a in [
                                $t('AInputDate.Monday'),
                                $t('AInputDate.Tuesday'),
                                $t('AInputDate.Wednesday'),
                                $t('AInputDate.Thursday'),
                                $t('AInputDate.Friday'),
                                $t('AInputDate.Saturday'),
                                $t('AInputDate.Sunday'),
                            ]"
                            :key="a"
                            style="width: 14.2857%"
                            class="c-f-h c-f-center-center"
                            :class="[
                                `c-font-size-${mySize}`,
                                `c-height-${mySize}`,
                                `c-front-color-${myColor}-reverse`,
                            ]"
                        >
                            {{ a }}
                        </div>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <div
                            v-for="a in getDayIndexOfFirstDate(
                                tempResult.Y,
                                tempResult.M
                            )"
                            :key="a"
                            style="width: 14.2857%"
                        ></div>
                        <a-button
                            v-for="a in getArrayFromNumberSpan(
                                1,
                                getDaysCountOfMonth(tempResult.Y, tempResult.M)
                            )"
                            :key="a + 100"
                            style="width: 14.2857%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="dateClick(a)"
                        >
                            {{ a }}
                        </a-button>
                    </div>
                </div>
                <div v-else-if="isShowHour" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            :title="$t('AInputDate.SelectDay')"
                            @click="
                                isShowDate = true;
                                isShowHour = false;
                            "
                            ><span>{{
                                tempResultInDayjs.format("YYYY-MM-DD")
                            }}</span>
                            <span
                                >&#160;&#160;<span class="animate-flash"
                                    >__</span
                                >:__:__</span
                            >
                        </a-button>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastDay')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(-1, 'day')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextDay')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(1, 'day')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <a-button
                            v-for="a in 24"
                            :key="a"
                            style="width: 16.6666%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="hourClick(a - 1)"
                        >
                            {{ paddingLeft(a - 1, 2) }}
                        </a-button>
                    </div>
                </div>
                <div v-else-if="isShowMinute" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            :title="$t('AInputDate.SelectHour')"
                            @click="
                                isShowHour = true;
                                isShowMinute = false;
                            "
                            ><span>{{
                                tempResultInDayjs.format("YYYY-MM-DD HH")
                            }}</span>
                            <span
                                >:<span class="animate-flash">__</span>:__</span
                            >
                        </a-button>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastHour')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(-1, 'hour')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextHour')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(1, 'hour')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <a-button
                            v-for="a in 60"
                            :key="a"
                            style="width: 10%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            class="c-p-0"
                            @click="minuteClick(a - 1)"
                        >
                            {{ paddingLeft(a - 1, 2) }}
                        </a-button>
                    </div>
                </div>
                <div v-else-if="isShowSecond" class="c-f-v c-w-100">
                    <div class="c-f-h c-f-between-center">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            :title="$t('AInputDate.SelectMinute')"
                            @click="
                                isShowMinute = true;
                                isShowSecond = false;
                            "
                            ><span>{{
                                tempResultInDayjs.format("YYYY-MM-DD HH:mm")
                            }}</span>
                            <span>:<span class="animate-flash">__</span></span>
                        </a-button>
                        <a-control-group direction="v">
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.LastMinute')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(-1, 'minute')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-up"></span>
                            </a-button>
                            <a-button
                                :color="myColor"
                                :size="mySize"
                                :sharp="mySharp"
                                :square="true"
                                :plain="true"
                                :title="$t('AInputDate.NextMinute')"
                                :halfHeight="true"
                                @click="
                                    tempValue = tempResultInDayjs
                                        .add(1, 'minute')
                                        .toDate()
                                "
                            >
                                <span class="fa fa-caret-down"></span>
                            </a-button>
                        </a-control-group>
                    </div>
                    <div class="c-f-h c-f-wrap">
                        <a-button
                            v-for="a in 60"
                            :key="a"
                            style="width: 10%"
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            class="c-p-0"
                            @click="secondClick(a - 1)"
                        >
                            {{ paddingLeft(a - 1, 2) }}
                        </a-button>
                    </div>
                </div>
                <div
                    class="c-f-h c-f-end-center c-b-t"
                    :class="[`c-m-t-${mySize}`]"
                >
                    <div :class="[`c-m-t-${mySize}`]">
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="input(new Date())"
                        >
                            {{ $t("AInputDate.Now") }}
                        </a-button>
                        <a-button
                            :color="myColor"
                            :size="mySize"
                            :sharp="mySharp"
                            :plain="true"
                            @click="input(tempValue)"
                        >
                            {{ $t("AInputDate.Done") }}
                        </a-button>
                    </div>
                </div>
            </div>
        </template>
    </a-dropdown>
</template>

<style lang="scss" scoped>
@import "../scss/vars";

@keyframes animate-flash {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 0;
    }
    51% {
        opacity: 1;
    }
    99% {
        opacity: 1;
    }
}

.pop {
    background-color: $defaultBgColor;
    box-sizing: border-box;

    .animate-flash {
        animation: animate-flash 1000ms infinite;
    }
}
</style>

<script>
import AInputString from './AInputString.vue'
import AButton from './AButton.vue'
import AControlGroup from './AControlGroup.vue'
import ADropdown from './ADropdown.vue'
import utils from "../common/utils"
import dayjs from 'dayjs'
import inputMixin from "../mixins/inputMixin"

export default {
    name: 'AInputDate',
    components: { AInputString, AButton, AControlGroup, ADropdown },
    mixins: [inputMixin],
    props: {
        value: {
            type: Date,
            default: null
        },
        format: {
            type: String,
            default: 'YYYY-MM-DD HH:mm:ss',
        },
        /**
         * 对齐到target的位置
         */
        popPlacement: {
            type: String,
            default: 'bottom-start'
        },
        clearable: {
            type: Boolean,
            default: true,
        },
        placeholder: {
            type: String,
            default: null
        },
        attachButtonShown: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        return {
            popShown: false,
            isShowYear: false,
            isShowMonth: false,
            isShowDate: false,
            isShowHour: false,
            isShowMinute: false,
            isShowSecond: false,
            currentYearTimespan: {
                min: 0,
                max: 0
            },
            tempValue: null,
        }
    },
    computed: {
        displayText() {
            return this.value ? dayjs(this.value).format(this.format) : null
        },
        tempResult() {
            return this.getResultFromDate(this.tempValue)
        },
        tempResultInDayjs() {
            return dayjs(this.tempValue)
        },
        sizePackage() {
            return utils.getSizePackageByName(this.mySize)
        },
        popWidth() {
            return this.sizePackage.size * 10 + this.sizePackage.space * 2
        },
        watermarkFontSize() {
            return this.sizePackage.size * 3
        },
    },
    watch: {
        popShown(val) {
            if (val) {
                this.showSelector()
            }
        },
    },
    methods: {
        showSelector() {
            this.isShowYear = false
            this.isShowMonth = false
            this.isShowDate = false
            this.isShowHour = false
            this.isShowMinute = false
            this.isShowSecond = false

            if (this.format.indexOf("M") == -1) {
                this.isShowYear = true
            } else if (this.format.indexOf("D") == -1) {
                this.isShowMonth = true
            } else {
                this.isShowDate = true
            }

            let now = new Date()
            let nowYear = now.getFullYear()
            this.currentYearTimespan.min = Math.floor(nowYear / 10) * 10 - 10
            this.currentYearTimespan.max = Math.floor(nowYear / 10) * 10 + 9
            this.tempValue = this.value || now
        },
        input(val) {
            this.$emit("update:value", val)
            this.popShown = false
        },
        getResultFromDate(dt) {
            if (!dt) {
                return {}
            }
            return {
                Y: dt.getFullYear(),
                M: dt.getMonth(),
                D: dt.getDate(),
                H: dt.getHours(),
                m: dt.getMinutes(),
                s: dt.getSeconds()
            }
        },
        getArrayFromNumberSpan(a, b) {
            let arr = []
            for (let i = a; i <= b; i++) {
                arr.push(i)
            }
            return arr
        },
        isLeapYear(year) {
            if (year % 4 !== 0) {
                return false
            }
            if (year % 100 == 0) {
                return false
            }
            return true
        },
        getDaysCountOfMonth(year, month) {
            //month是从Date.getMonth()取得，所以是从0开始
            if (month == 1) {
                return this.isLeapYear(year) ? 29 : 28
            } else if ([0, 2, 4, 6, 7, 9, 11].indexOf(month) > -1) {
                return 31
            } else {
                return 30
            }
        },
        getDayIndexOfFirstDate(year, month) {
            let dt = new Date(year, month, 1)
            let day = dt.getDay()
            let index = (day || 7) - 1
            return index
        },
        paddingLeft(string, totalCount) {
            return string.toString().padStart(totalCount, "0")
        },
        yearClick(year) {
            this.tempValue = this.tempResultInDayjs.set('year', year).toDate()
            if (this.format.indexOf("M") != -1) {
                this.isShowYear = false
                this.isShowMonth = true
            }
        },
        monthClick(month) {
            this.tempValue = this.tempResultInDayjs.set('month', month - 1).toDate()
            if (this.format.indexOf("D") != -1) {
                this.isShowMonth = false
                this.isShowDate = true
            }
        },
        dateClick(date) {
            this.tempValue = this.tempResultInDayjs.set('date', date).toDate()
            if (this.format.indexOf("H") != -1) {
                this.isShowDate = false
                this.isShowHour = true
            }
        },
        hourClick(hour) {
            this.tempValue = this.tempResultInDayjs.set('hour', hour).toDate()
            if (this.format.indexOf("m") != -1) {
                this.isShowHour = false
                this.isShowMinute = true
            }
        },
        minuteClick(minute) {
            this.tempValue = this.tempResultInDayjs.set('minute', minute).toDate()
            if (this.format.indexOf("s") != -1) {
                this.isShowMinute = false
                this.isShowSecond = true
            }
        },
        secondClick(second) {
            this.tempValue = this.tempResultInDayjs.set('second', second).toDate()
            this.input(this.tempValue)
        },
    }
}
</script>